﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Dynamic;
using System.Transactions;
using PagedList;
using Sovigaz.DataProvider;
using Utilities;
using System.Data.Entity.Infrastructure;

namespace Sovigaz.Permission.Repositories
{
    public class OrderRepository : GenericRepository
    {
        public OrderRepository()
            : base("OrderID")
        {
        }

        public ICollection<OrderComplex> Orders { get; set; }

        #region Get

        public OrderRepository GetList(string whereClause, string orderBy, string orderDirection, int pageNumber)
        {
            var orders = _context.Orders
                .Join(_context.Partners, o=>o.PartnerID,p=>p.PartnerID,
                (o,p)=> new OrderComplex()
                {
                    OrderID=o.OrderID,
                    PartnerID=o.PartnerID,
                    PartnerName=p.PartnerName,
                    OrderCode=o.OrderCode,
                    OrderDate=o.OrderDate,
                    DeliveryDate=o.DeliveryDate,
                    Status=o.Status,
                    Type=o.Type,
                    Description=o.Description,
                    IsDeleted=o.IsDeleted
                })
                .Where(whereClause)
                .OrderBy(String.Format("{0} {1}", orderBy.Trim(), orderDirection.Trim()))
                .ToPagedList(pageNumber, DefaultPageSize);

            TotalItemCount = orders.TotalItemCount;
            TotalItemOnPage = orders.Count;
            PageCount = orders.PageCount;
            PageNumber = orders.PageNumber;
            Orders = orders.ToList();

            return this;
        }

        public OrderRepository GetList(string whereClause, string orderBy, string orderDirection, int pageNumber, DateTime datefrom, DateTime dateto)
        {
            var orders = _context.Orders
                .Join(_context.Partners, o => o.PartnerID, p => p.PartnerID,
                (o, p) => new OrderComplex()
                {
                    OrderID = o.OrderID,
                    PartnerID = o.PartnerID,
                    PartnerName = p.PartnerName,
                    OrderCode = o.OrderCode,
                    OrderDate = o.OrderDate,
                    DeliveryDate = o.DeliveryDate,
                    Status = o.Status,
                    Type = o.Type,
                    Description = o.Description,
                    IsDeleted = o.IsDeleted
                })
                .Where(whereClause)
                .Where(p => p.OrderDate >= datefrom.Date && p.OrderDate <= dateto.Date)
                .OrderBy(String.Format("{0} {1}", orderBy.Trim(), orderDirection.Trim()))
                .ToPagedList(pageNumber, DefaultPageSize);

            TotalItemCount = orders.TotalItemCount;
            TotalItemOnPage = orders.Count;
            PageCount = orders.PageCount;
            PageNumber = orders.PageNumber;
            Orders = orders.ToList();

            return this;
        }

        public List<Order> GetListByStatus(string status)
        {
            if(status=="I")
                return _context.Orders.Where(p => !p.IsDeleted && (p.Status == status || p.Status=="N")).ToList();
            return _context.Orders.Where(p => !p.IsDeleted && p.Status == status).ToList();
        }

        public Order GetByID(int id)
        {
            return _context.Orders.FirstOrDefault(p => p.OrderID == id && !p.IsDeleted);
        }

        #endregion

        public void Delete(int id)
        {
            var item = GetByID(id);
            if (item != null && item.Status == "N")
            {
                _context.Orders.Remove(item);
                var repository = new OrderLineRepository();
                repository.DeleteByOrderID(item.OrderID);
            }
            _context.SaveChanges();
        }

        public void Delete(string[] idArr)
        {
            foreach (var id in idArr)
                Delete(ConvertUtility.IntParse(id));
        }

        public int Update(Order order)
        {
            var update = new Order();

            using (var scope = new TransactionScope())
            {
                if (order.OrderID > 0)
                {
                    update = GetByID(order.OrderID);
                    if (!Utility.ArrayEqual(update.Tstamp, order.Tstamp))
                        throw ExceptionHelper.CreateHttpResponseException("Dữ liệu đã bị cập nhật bởi người sử dụng khác.");
                }
                update.OrderID = order.OrderID;
                update.OrderCode = order.OrderCode;
                update.PartnerID = order.PartnerID;
                update.OrderDate = order.OrderDate;
                update.DeliveryDate = order.DeliveryDate;
                update.Status = order.Status;
                update.Type = order.Type;
                update.Description = order.Description;

                if (update.OrderID == 0)
                    _context.Orders.Add(update);

                _context.SaveChanges();
                _context.Entry(update).Reload();
                var orderLinerepository = new OrderLineRepository();
                orderLinerepository.Update(order.OrderLines, update.OrderID, scope);
                scope.Complete();
            }

            return update.OrderID;
        }
       
        public int GetNextIndex()
        {
            if (_context.Orders.FirstOrDefault() == null) return 1;
            return _context.Orders.Max(p => p.OrderID) + 1;
        }

        public void UpdateStatus(int orderID, string status)
        {
            Order order = GetByID(orderID);
            order.Status = status;
            _context.SaveChanges();
        }

        public bool CanEdit(int id)
        {
            if (id>0 && GetByID(id).Status != "N") return false;
            return true;
        }
    }
}
